import 'package:get/get.dart';
import 'package:fall_data_base/fall_data_base.dart';
import 'package:froom/froom.dart';
import 'package:sqflite/sqflite.dart' as sqflite;

/// 数据库工具类，使用 GetX 管理数据库实例
class DbUtil {
  /// 注册数据库实例
  /// [dbDto] 数据库传输对象
  /// [name] 数据库名称，可选，默认使用 Db.Default
  static void registerDb(DbDto dbDto, {String? name}) {
    final dbName = name ?? DB.Default;
    Get.put<DbDto>(dbDto, tag: dbName);
  }

  /// 获取数据库实例
  /// [name] 数据库名称，可选，默认使用 Db.Default
  /// 返回 DbDto 数据库传输对象
  static DbDto getDb({String? name}) {
    final dbName = name ?? DB.Default;
    return Get.find<DbDto>(tag: dbName);
  }

  /// 检查数据库是否已注册
  /// [name] 数据库名称，可选，默认使用 Db.Default
  /// 返回 true 如果数据库已注册，否则返回 false
  static bool isDbRegistered({String? name}) {
    final dbName = name ?? DB.Default;
    return Get.isRegistered<DbDto>(tag: dbName);
  }

  /// 移除数据库实例
  /// [name] 数据库名称，可选，默认使用 Db.Default
  /// 返回 true 如果成功移除，否则返回 false
  static Future<bool> removeDb({String? name}) async {
    final dbName = name ?? DB.Default;
    return await Get.delete<DbDto>(tag: dbName);
  }

  static Future<sqflite.Database> openDbPath(
    String path,
    List<Migration> migrations, [
    Callback? callback,
  ]) async {
    final databaseOptions = sqflite.OpenDatabaseOptions(
      version: 1,
      onConfigure: (database) async {
        await database.execute('PRAGMA foreign_keys = ON');
        await callback?.onConfigure?.call(database);
      },
      onOpen: (database) async {
        await callback?.onOpen?.call(database);
      },
      onUpgrade: (database, startVersion, endVersion) async {
        await MigrationAdapter.runMigrations(
            database, startVersion, endVersion, migrations);

        await callback?.onUpgrade?.call(database, startVersion, endVersion);
      },
      onCreate: (database, version) async {
        await database.execute(
            'CREATE TABLE IF NOT EXISTS `Task` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `message` TEXT NOT NULL, `isRead` INTEGER, `timestamp` INTEGER NOT NULL, `status` INTEGER, `type` TEXT)');

        await callback?.onCreate?.call(database, version);
      },
    );
    return sqfliteDatabaseFactory.openDatabase(path, options: databaseOptions);
  }

  static Future<sqflite.Database> openDb(
    String? name,
    List<Migration> migrations, [
    Callback? callback,
  ]) async {
    final path = name != null
        ? await sqfliteDatabaseFactory.getDatabasePath(name!)
        : ':memory:';
    return openDbPath(path, migrations, callback);
  }
}
